#pragma once
#include "epoll.h"
#include "util.h"
#include<memory>
#include<cstring>
#include<iostream>

Epoll::Epoll(/* args */)
{
}

Epoll::~Epoll()
{
}

// int Epoll::addFd(int fd, uint32_t events)
// {
//     ev.data.fd=fd;
//     ev.events=events;
//     int res = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
//     errif(res==-1, "epoll addFd error");
//     return res;
// }

std::vector<std::unique_ptr<Channel>> Epoll::poll() {
    std::vector<std::unique_ptr<Channel>> ret;
    int nfds = epoll_wait(epfd, events, MAX_EVENTS, -1);
    for (int i=0;i<nfds;++i) {
        Channel *ch = (Channel *)events[i].data.ptr;
        std::unique_ptr<Channel> ch_p(ch);
        ret.push_back(std::move(ch_p));
    }
    return ret;
}

void Epoll::updateChannel(Channel *channel){
    int fd = channel->getFd();  //拿到Channel的文件描述符
    struct epoll_event ev;
    bzero(&ev, sizeof(ev));
    ev.data.ptr = (void *)channel;
    ev.events = channel->getEvents();   //拿到Channel希望监听的事件
    if(!channel->getInEpoll()){
        errif(epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) == -1, "epoll add error");//添加Channel中的fd到epoll
        channel->setInEpoll();
    } else{
        errif(epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &ev) == -1, "epoll modify error");//已存在，则修改
    }
}